package com.shigen.file.config;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.DES;
import java.nio.charset.StandardCharsets;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * token规则验证工具类
 *
 * @author shigenfu
 */
@Component
@Slf4j
public class TokenUtil {

  @Resource
  private ConfigProperty configProperty;
  /**
   * 真实token长度
   */
  private static final int TOKEN_LEN = 10;

  /**
   * 获得加密之后的token
   */
  public String getEncryptToken() {
    //构建 key的最小长度必须为 8
    String key = StrUtil.padAfter(configProperty.getDesKey(), 8, '*');
    DES des = SecureUtil.des(key.getBytes(StandardCharsets.UTF_8));
    String token = RandomUtil.randomString(TOKEN_LEN);
    return des.encryptHex(token);
  }

  /**
   * 获得带有时间戳加密之后的token
   */
  public String getTokenWithTimestamp() {
    //构建 key的最小长度必须为8
    String key = StrUtil.padAfter(configProperty.getDesKey(), 8, '*');
    DES des = SecureUtil.des(key.getBytes(StandardCharsets.UTF_8));
    String token = RandomUtil.randomString(TOKEN_LEN) + DateUtil.currentSeconds();
    return des.encryptHex(token);
  }

  /**
   * 解密不含时间戳的加密token
   */
  public String parseToken(String token) {
    //构建 key的最小长度必须为8
    String key = StrUtil.padAfter(configProperty.getDesKey(), 8, '*');
    DES des = SecureUtil.des(key.getBytes(StandardCharsets.UTF_8));
    return des.decryptStr(token);
  }

  /**
   * 解析带时间戳加密的token
   */
  public String parseTokenWithTimestamp(String token) {
    String parseToken = this.parseToken(token);
    int length = parseToken.length();
    try {
      String substring = parseToken.substring(0, length - 10);
      log.info("{}: realToken: {}", DateUtil.now(), substring);
      return substring;
    } catch (IndexOutOfBoundsException e) {
      log.error("token解析错误，exception: {}", e.getMessage());
    }
    return "";
  }

  /**
   * 验证token是否过期了
   */
  public Boolean verify(String token) {
    String s = parseToken(token);
    // 最后10位为时间戳的数字
    String timestamp = s.substring(s.length() - 10);
    boolean aLong = NumberUtil.isLong(timestamp);
    if (!aLong) {
      return false;
    }
    // 获得当前时间戳比较
    return DateUtil.currentSeconds() - Long.parseLong(timestamp) <= configProperty.getTokenDelay();
  }
}
